<?php


namespace App\Imports;

use App\Exceptions\ApiException;
use App\Models\PhotoArchives;
use App\Services\BaseService;
use App\Services\PhotoClassifyService;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithBatchInserts;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use Maatwebsite\Excel\Concerns\WithColumnLimit;
use Maatwebsite\Excel\Concerns\WithLimit;
use Maatwebsite\Excel\Concerns\WithStartRow;

/**
 * Class BookTitleImport
 * @package App\Imports
 * 适用于 29号文件
 */
class PhotoArchivesImport implements ToModel, WithChunkReading, WithStartRow, WithColumnLimit, WithBatchInserts, WithLimit
{
    protected $partCompanyId;
    protected $photoClassifyId;
    protected $perPage;
    protected $chunkSize;
    protected $startRow;
    protected $endColumn;
    protected $batchSize;
    protected $cache;
    protected $stop;
    protected $baseArchivesNo;
    protected $bookTitleInstance;
    protected $importCountKey;


    public function __construct($projectId, $partCompanyId, $photoClassifyId, $importCountKey)
    {
        $this->importCountKey       = $importCountKey; //存放导入的案卷数
        $this->stop                 = 0;    //0继续读取，1停止读取
        $this->limit                = 5000; //只读取前5000行
        $this->chunkSize            = 100;  //将数据拆成小块读取
        $this->startRow             = 4;    //从第几行开始
        $this->endColumn            = 'F';  //指定到那一列为止
        $this->batchSize            = 100;  //批量写入的数据大小
        $this->projectId            = $projectId; //所属项目
        $this->partCompanyId        = $partCompanyId; //参建单位
        $this->photoClassifyId      = $photoClassifyId; //项目分类目录
        $this->baseArchivesNo       = PhotoClassifyService::getBaseArchivesNo($photoClassifyId); //该项目分类下，基础档案号，导入的案卷文件档案号，必须属于基础档案号下
        $this->photoArchiveInstance = (new BaseService())->getPhotoArchiveInstance($partCompanyId, $photoClassifyId);
    }

    public function model(array $row)
    {
        if ($row[0] == 'ee') $this->stop = 1; //如果出现了指定【终止标识】，不再写入
        /**
         * redis()集合添加档案号，如果加入成功，说明是新档案号
         */
        $this->baseArchivesNo = format_archives_no(trim($this->baseArchivesNo));
        if (!$this->stop && is_numeric($row[0])) {
            $archivesNo = format_archives_no(trim($row[1])); //档案号
            if (!str_contains($archivesNo, $this->baseArchivesNo)) {
                throw new ApiException("档案号跟项目分类不匹配！");
            }
            if (!redis()->sadd('photo_archives_no' . $this->importCountKey, $archivesNo)) { //如果加入集合失败，会软删除原有的，再继续写入新的，相当于覆盖
                $this->photoArchiveInstance->where('archives_no', $archivesNo)->delete();
            }
            redis()->incr($this->importCountKey, 1); //导入的数量增加
            $this->photoArchiveInstance->updateOrCreate([
                'project_id'        => $this->projectId,        //所属项目
                'part_company_id'   => $this->partCompanyId,    //参建单位
                'photo_classify_id' => $this->photoClassifyId,  //照片分类
            ], [
                'company_id'        => company_id(),            //所属公司
                'serial_no'         => $row[0],                 //序号
                'archives_no'       => $archivesNo,             //档案号
                'title'             => format_str($row[2]),     //案卷题名
                'page_num'          => to_int($row[3]),         //张数
                'store_period'      => format_str($row[4]),     //保管期限
                'remark'            => format_str($row[5]),     //备注
                "creator_id"        => user_id(),
                'created_at'        => now(),
                'updated_at'        => now(),
                'is_need_check'     => 1, //如果案卷进行了修改，要重新检查
            ]);
        }
    }

    /**
     * 将数据拆成小块进行导入，减小内存占用
     *
     * @return int
     */
    public function chunkSize(): int
    {
        return $this->chunkSize;
    }

    /**
     * 直接过滤表头，第一块数据含表头
     *
     * @return int
     */
    public function startRow(): int
    {
        return $this->startRow;
    }

    /**
     * 指定到那一列为止，G代表读取到G列就不再读取
     *
     * @return string
     */
    public function endColumn(): string
    {
        return $this->endColumn;
    }

    /**
     * 批量写入的数据大小
     *
     * @return int
     */
    public function batchSize(): int
    {
        return $this->batchSize;
    }

    public function limit(): int
    {
        return $this->limit;
    }

}
